﻿#region Copyright(c) 2006 ZO, All right reserved.

// -----------------------------------------------------------------------------
// Copyright(c) 2006 ZO, All right reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1.  Redistribution of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//   2.  Redistribution in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//   3.  The name of the author may not be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------

#endregion

#region Using directives

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using ZO.SmartCore.My4CSharp.Properties;
using ZO.SmartCore.Threading;
using ArgumentException= ZO.SmartCore.Core.ArgumentException;
using ArgumentNullException= ZO.SmartCore.Core.ArgumentNullException;

#endregion

namespace ZO.SmartCore.My4CSharp
{
    /// <summary>Provides properties and methods for working with drives, files, and directories.</summary>
    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Advanced)]
    [HostProtection(SecurityAction.LinkDemand, Resources = HostProtectionResource.ExternalProcessMgmt)]
    public class FileSystem
    {
        #region Constructors

        #endregion

        #region Destructor

        #endregion

        #region Fields

        private static readonly ThreadSafeObjectProvider<SpecialDirectories> _SpecialDirectories =
            new ThreadSafeObjectProvider<SpecialDirectories>();


        private static char[] SeparatorChars =
            new char[]
                {
                    Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar, Path.VolumeSeparatorChar,
                    Path.PathSeparator
                };

        #endregion

        #region Events

        #endregion

        #region Operators

        #endregion

        #region Properties

        /// <summary>Gets or sets the current directory.</summary>
        /// <returns>String.</returns>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string CurrentDirectory
        {
            get { return NormalizePath(Directory.GetCurrentDirectory()); } // get
            set { Directory.SetCurrentDirectory(value); } // set
        } // CurrentDirectory

        /// <summary>Returns a read-only collection of all available drive names.</summary>
        /// <returns>System.Collections.ObjectModel.ReadOnlyCollection (of System.IO.DriveInfo)</returns>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<DriveInfo> Drives
        {
            get
            {
                Collection<DriveInfo> collection1 = new Collection<DriveInfo>();
                DriveInfo[] infoArray1 = DriveInfo.GetDrives();
                for (int num1 = 0; num1 < infoArray1.Length; num1++)
                {
                    DriveInfo info1 = infoArray1[num1];
                    collection1.Add(info1);
                } // for
                return new ReadOnlyCollection<DriveInfo>(collection1);
            } // get
        } // Drives


        /// <summary>Gets an object that provides properties for accessing commonly referenced directories.</summary>
        /// <returns>This property returns the My.Computer.FileSystem.SpecialDirectories Object for the computer.</returns>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public SpecialDirectories SpecialDirectories
        {
            get { return _SpecialDirectories.Instance; } // get
        } // SpecialDirectories

        /// <summary>Creates a uniquely named zero-byte temporary file on disk and returns the full path of that file.</summary>
        /// <returns>String containing the full path of the temporary file.</returns>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string GetTempFileName
        {
            get { return Path.GetTempFileName(); }
        } // GetTempFileName

        #endregion

        #region Method

        /// <summary>Moves a directory from one location to another.</summary>
        /// <param name="destinationDirectoryName">String. Path of the directory to which the source directory is being moved. Required. </param>
        /// <param name="sourceDirectoryName">String. Path of the directory to be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName)
        {
            CopyOrMoveDirectory(CopyOrMove.Move, sourceDirectoryName, destinationDirectoryName, false,
                                UIOptionInternal.NoUI, UICancelOption.ThrowException);
        } // MoveDirectory

        /// <summary>Moves a directory from one location to another.</summary>
        /// <param name="showUI"><see cref="UIOption"/>. Specifies whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        /// <param name="destinationDirectoryName">String. Path of the directory to which the source directory is being moved. Required. </param>
        /// <param name="sourceDirectoryName">String. Path of the directory to be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName, UIOption showUI)
        {
            CopyOrMoveDirectory(CopyOrMove.Move, sourceDirectoryName, destinationDirectoryName, false,
                                ToUIOptionInternal(showUI), UICancelOption.ThrowException);
        } // MoveDirectory

        /// <summary>Moves a directory from one location to another.</summary>
        /// <param name="overwrite">Boolean. Specifies whether existing directories should be overwritten. Default is False. Required. </param>
        /// <param name="destinationDirectoryName">String. Path of the directory to which the source directory is being moved. Required. </param>
        /// <param name="sourceDirectoryName">String. Path of the directory to be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName, bool overwrite)
        {
            CopyOrMoveDirectory(CopyOrMove.Move, sourceDirectoryName, destinationDirectoryName, overwrite,
                                UIOptionInternal.NoUI, UICancelOption.ThrowException);
        } // MoveDirectory

        /// <summary>Moves a directory from one location to another.</summary>
        /// <param name="onUserCancel">UICancelOption Enumeration. Specifies whether or not an exception is thrown when the user cancels the operation. Default is UICancelOption.ThrowException. Required. </param>
        /// <param name="showUI"><see cref="UIOption"></see>. Specifies whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        /// <param name="destinationDirectoryName">String. Path of the directory to which the source directory is being moved. Required. </param>
        /// <param name="sourceDirectoryName">String. Path of the directory to be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveDirectory(string sourceDirectoryName, string destinationDirectoryName, UIOption showUI,
                                  UICancelOption onUserCancel)
        {
            CopyOrMoveDirectory(CopyOrMove.Move, sourceDirectoryName, destinationDirectoryName, false,
                                ToUIOptionInternal(showUI), onUserCancel);
        } // MoveDirectory


        /// <summary>Moves a file to a new location.</summary>
        /// <param name="sourceFileName">String. Path of the file to be moved. Required. </param>
        /// <param name="destinationFileName">String. Path of the directory into which the file should be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveFile(string sourceFileName, string destinationFileName)
        {
            CopyOrMoveFile(CopyOrMove.Move, sourceFileName, destinationFileName, false, UIOptionInternal.NoUI,
                           UICancelOption.ThrowException);
        } // MoveFile

        /// <summary>Moves a file to a new location.</summary>
        /// <param name="sourceFileName">String. Path of the file to be moved. Required. </param>
        /// <param name="showUI">UIOption Enumeration. Specifies whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        /// <param name="destinationFileName">String. Path of the directory into which the file should be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveFile(string sourceFileName, string destinationFileName, UIOption showUI)
        {
            CopyOrMoveFile(CopyOrMove.Move, sourceFileName, destinationFileName, false, ToUIOptionInternal(showUI),
                           UICancelOption.ThrowException);
        } // MoveFile

        /// <summary>Moves a file to a new location.</summary>
        /// <param name="sourceFileName">String. Path of the file to be moved. Required. </param>
        /// <param name="overwrite">Boolean. Specifies whether to overwrite existing files. Default is False. Required. </param>
        /// <param name="destinationFileName">String. Path of the directory into which the file should be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveFile(string sourceFileName, string destinationFileName, bool overwrite)
        {
            CopyOrMoveFile(CopyOrMove.Move, sourceFileName, destinationFileName, overwrite, UIOptionInternal.NoUI,
                           UICancelOption.ThrowException);
        } // MoveFile

        /// <summary>Moves a file to a new location.</summary>
        /// <param name="sourceFileName">String. Path of the file to be moved. Required. </param>
        /// <param name="onUserCancel">UICancelOption Enumeration. Specifies whether or not an exception is thrown when the user cancels the operation. Default is UICancelOption.ThrowException. Required. </param>
        /// <param name="showUI">UIOption Enumeration. Specifies whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        /// <param name="destinationFileName">String. Path of the directory into which the file should be moved. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void MoveFile(string sourceFileName, string destinationFileName, UIOption showUI,
                             UICancelOption onUserCancel)
        {
            CopyOrMoveFile(CopyOrMove.Move, sourceFileName, destinationFileName, false, ToUIOptionInternal(showUI),
                           onUserCancel);
        } // MoveFile

        /// <summary>Deletes a directory.</summary>
        /// <param name="recycle">RecycleOption Enumeration. Specifies whether or not the deleted file should be sent to the Recycle Bin. Default is RecycleOption.DeletePermanently. </param>
        /// <param name="directory">String. Directory to be deleted. Required. </param>
        /// <param name="showUI">UIOption Enumeration. Specifies whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        /// <param name="onUserCancel">UICancelOption Enumeration. Specifies whether to throw an exception if the user clicks Cancel. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void DeleteDirectory(string directory, UIOption showUI, RecycleOption recycle,
                                    UICancelOption onUserCancel)
        {
            DeleteDirectoryInternal(directory, DeleteDirectoryOption.DeleteAllContents, ToUIOptionInternal(showUI),
                                    recycle, onUserCancel);
        } // DeleteDirectory

        private static void VerifyDeleteDirectoryOption(string argName, DeleteDirectoryOption argValue)
        {
            if ((argValue != DeleteDirectoryOption.DeleteAllContents) &&
                (argValue != DeleteDirectoryOption.ThrowIfDirectoryNonEmpty))
            {
                throw new InvalidEnumArgumentException(argName, (int) argValue, typeof (DeleteDirectoryOption));
            } // if
        } // VerifyDeleteDirectoryOption


        private static void VerifyRecycleOption(string argName, RecycleOption argValue)
        {
            if ((argValue != RecycleOption.DeletePermanently) && (argValue != RecycleOption.SendToRecycleBin))
            {
                throw new InvalidEnumArgumentException(argName, (int) argValue, typeof (RecycleOption));
            } // if
        } // VerifyRecycleOption


        private static void ShellDelete(string FullPath, UIOptionInternal ShowUI, RecycleOption recycle,
                                        UICancelOption OnUserCancel, FileOrDirectory FileOrDirectory)
        {
            NativeMethods.ShFileOperationFlags flags1 = GetOperationFlags(ShowUI);
            if (recycle == RecycleOption.SendToRecycleBin)
            {
                flags1 |= NativeMethods.ShFileOperationFlags.FOF_ALLOWUNDO;
            } // if
            ShellFileOperation(NativeMethods.SHFileOperationType.FO_DELETE, flags1, FullPath, null, OnUserCancel,
                               FileOrDirectory);
        } // ShellDelete


        /// <summary>Deletes a directory.</summary>
        /// <param name="recycle">RecycleOption Enumeration. Specifies whether or not the deleted file should be sent to the Recycle Bin. Default is RecycleOption.DeletePermanently. </param>
        /// <param name="directory">String. Directory to be deleted. Required. </param>
        /// <param name="showUI">UIOption Enumeration. Specifies whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void DeleteDirectory(string directory, UIOption showUI, RecycleOption recycle)
        {
            DeleteDirectoryInternal(directory, DeleteDirectoryOption.DeleteAllContents, ToUIOptionInternal(showUI),
                                    recycle, UICancelOption.ThrowException);
        } // DeleteDirectory


        /// <summary>Deletes a directory.</summary>
        /// <param name="directory">String. Directory to be deleted. Required. </param>
        /// <param name="onDirectoryNotEmpty">DeleteDirectoryOption Enumeration. Specifies what should be done when a directory that is to be deleted contains files or directories. Default is DeleteDirectoryOption.DeleteAllContents.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void DeleteDirectory(string directory, DeleteDirectoryOption onDirectoryNotEmpty)
        {
            DeleteDirectoryInternal(directory, onDirectoryNotEmpty, UIOptionInternal.NoUI,
                                    RecycleOption.DeletePermanently, UICancelOption.ThrowException);
        } // DeleteDirectory


        private static void DeleteDirectoryInternal(string directory, DeleteDirectoryOption onDirectoryNotEmpty,
                                                    UIOptionInternal showUI, RecycleOption recycle,
                                                    UICancelOption onUserCancel)
        {
            VerifyDeleteDirectoryOption("onDirectoryNotEmpty", onDirectoryNotEmpty);
            VerifyRecycleOption("recycle", recycle);
            VerifyUICancelOption("onUserCancel", onUserCancel);
            string text1 = Path.GetFullPath(directory);
            DemandDirectoryPermission(text1, FileIOPermissionAccess.Write);
            ThrowIfDevicePath(text1);
            if (!Directory.Exists(text1))
            {
                throw new DirectoryNotFoundException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryNotFound_Path,
                                  new string[] {directory}));
            } // if
            if (IsRoot(text1))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryIsRoot_Path,
                                  new string[] {directory}));
            } // if
            if ((showUI != UIOptionInternal.NoUI) && Environment.UserInteractive)
            {
                ShellDelete(text1, showUI, recycle, onUserCancel, FileOrDirectory.Directory);
            } // if
            else
            {
                Directory.Delete(text1, onDirectoryNotEmpty == DeleteDirectoryOption.DeleteAllContents);
            } // else
        } // DeleteDirectoryInternal


        /// <summary>Deletes a file.</summary>
        /// <param name="file">String. Name and path of the file to be deleted. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void DeleteFile(string file)
        {
            DeleteFileInternal(file, UIOptionInternal.NoUI, RecycleOption.DeletePermanently,
                               UICancelOption.ThrowException);
        } // DeleteFile


        private static void DeleteFileInternal(string file, UIOptionInternal showUI, RecycleOption recycle,
                                               UICancelOption onUserCancel)
        {
            VerifyRecycleOption("recycle", recycle);
            VerifyUICancelOption("onUserCancel", onUserCancel);
            string text1 = NormalizeFilePath(file, "file");
            new FileIOPermission(FileIOPermissionAccess.Write, text1).Demand();
            ThrowIfDevicePath(text1);
            if (!File.Exists(text1))
            {
                throw new FileNotFoundException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_FileNotFound_Path, new string[] {file}));
            } // if
            if ((showUI != UIOptionInternal.NoUI) && Environment.UserInteractive)
            {
                ShellDelete(text1, showUI, recycle, onUserCancel, FileOrDirectory.File);
            } // if
            else
            {
                File.Delete(text1);
            } // else
        } // DeleteFileInternal


        /// <summary>Deletes a file.</summary>
        /// <param name="file">String. Name and path of the file to be deleted. Required. </param>
        /// <param name="recycle">RecycleOption. Whether or not the deleted file should be sent to the Recycle Bin. Default is RecycleOption.DeletePermanently. Required. </param>
        /// <param name="showUI">UIOption. Whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void DeleteFile(string file, UIOption showUI, RecycleOption recycle)
        {
            DeleteFileInternal(file, ToUIOptionInternal(showUI), recycle, UICancelOption.ThrowException);
        } // DeleteFile


        /// <summary>Deletes a file.</summary>
        /// <param name="file">String. Name and path of the file to be deleted. Required. </param>
        /// <param name="recycle">RecycleOption. Whether or not the deleted file should be sent to the Recycle Bin. Default is RecycleOption.DeletePermanently. Required. </param>
        /// <param name="onUserCancel">UICancelOption. Specifies whether or not an exception is thrown when the user cancels the operation. Default is UICancelOption.ThrowException. Required. </param>
        /// <param name="showUI">UIOption. Whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void DeleteFile(string file, UIOption showUI, RecycleOption recycle, UICancelOption onUserCancel)
        {
            DeleteFileInternal(file, ToUIOptionInternal(showUI), recycle, onUserCancel);
        } // DeleteFile


        /// <summary>Returns a Boolean indicating whether the specified directory exists.</summary>
        /// <returns>True if the directory exists; otherwise False.</returns>
        /// <param name="directory">String. Path of the directory. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool DirectoryExists(string directory)
        {
            return Directory.Exists(directory);
        } // DirectoryExists


        /// <summary>Returns a Boolean indicating whether the specified file exists.</summary>
        /// <returns>Returns True if the file exists; otherwise this method returns False.</returns>
        /// <param name="file">String. Name and path of the file. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool FileExists(string file)
        {
            if (!string.IsNullOrEmpty(file) &&
                (file.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase) ||
                 file.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase)))
            {
                return false;
            } // if
            return File.Exists(file);
        } // FileExists

        /// <summary>Returns a Boolean indicating whether the specified file exists.</summary>
        /// <param name="file">String. Name and path of the file. Required. </param>
        /// <param name="throwException">throw exception if this is true</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public bool FileExists(string file, bool throwException)
        {
            bool ret = false;
            if (!String.IsNullOrEmpty(file) &&
                (file.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase) ||
                 file.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase)))
            {
                return ret;
            } // if


            ret = File.Exists(file);
            if (!ret)
            {
                if (throwException)
                {
                    throw new FileNotFoundException(
                        String.Format(CultureInfo.InvariantCulture, Resources.IO_FileNotFound_Path, new string[] {file}),
                        file);
                }
            } // if
            return ret;
        } // FileExists


        /// <summary>Returns a read-only collection of strings representing the names of files containing the specified text.</summary>
        /// <returns>Read-only collection of type String.</returns>
        /// <param name="containsText">String. The search text. Required.</param>
        /// <param name="directory">String. The directory to be searched. Required.</param>
        /// <param name="ignoreCase">Boolean. Whether the search should be case-sensitive or not. Default is True. Required.</param>
        /// <param name="searchType">SearchOption Enumeration. Whether to include subfolders. Default is SearchOption.SearchTopLevelOnly. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<string> FindInFiles(string directory, string containsText, bool ignoreCase,
                                                      SearchOption searchType)
        {
            return FindInFiles(directory, containsText, ignoreCase, searchType, null);
        } // FindInFiles


        /// <summary>Returns a read-only collection of strings representing the names of files containing the specified text.</summary>
        /// <returns>Read-only collection of type String.</returns>
        /// <param name="containsText">String. The search text. Required.</param>
        /// <param name="fileWildcards">Array of type String. Pattern to be matched. Required.</param>
        /// <param name="directory">String. The directory to be searched. Required.</param>
        /// <param name="ignoreCase">Boolean. Whether the search should be case-sensitive or not. Default is True. Required.</param>
        /// <param name="searchType">SearchOption Enumeration. Whether to include subfolders. Default is SearchOption.SearchTopLevelOnly. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<string> FindInFiles(string directory, string containsText, bool ignoreCase,
                                                      SearchOption searchType, params string[] fileWildcards)
        {
            IEnumerator<string> enumerator1 = null;
            ReadOnlyCollection<string> collection2 =
                FindFilesOrDirectories(FileOrDirectory.File, directory, searchType, fileWildcards);
            if (String.IsNullOrEmpty(containsText))
            {
                return collection2;
            } // if
            Collection<string> collection3 = new Collection<string>();
            try
            {
                enumerator1 = collection2.GetEnumerator();
                while (enumerator1.MoveNext())
                {
                    string text1 = enumerator1.Current;
                    if (FileContainsText(text1, containsText, ignoreCase))
                    {
                        collection3.Add(text1);
                    } // if
                } // while
            } // try
            finally
            {
                if (enumerator1 != null)
                {
                    enumerator1.Dispose();
                } // if
            } // finally
            return new ReadOnlyCollection<string>(collection3);
        } // FindInFiles

        private static void VerifySearchOption(string argName, SearchOption argValue)
        {
            if ((argValue != SearchOption.SearchAllSubdirectories) && (argValue != SearchOption.SearchTopLevelOnly))
            {
                throw new InvalidEnumArgumentException(argName, (int) argValue, typeof (SearchOption));
            } // if
        } // VerifySearchOption


        private static bool FileContainsText(string FilePath, string Text, bool IgnoreCase)
        {
            bool flag1;
            int num1 = 0x400;
            FileStream stream1 = null;
            try
            {
                stream1 = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                Encoding encoding1 = Encoding.Default;
                byte[] buffer1 = new byte[(num1 - 1) + 1];
                int num3;
                num3 = stream1.Read(buffer1, 0, buffer1.Length);
                if (num3 > 0)
                {
                    MemoryStream stream2 = new MemoryStream(buffer1, 0, num3);
                    StreamReader reader1 = new StreamReader(stream2, encoding1, true);
                    reader1.ReadLine();
                    encoding1 = reader1.CurrentEncoding;
                } // if
                int num4 = encoding1.GetMaxByteCount(Text.Length);
                int num2 = Math.Max(num4, num1);
                TextSearchHelper helper1 = new TextSearchHelper(encoding1, Text, IgnoreCase);
                if (num2 > num1)
                {
                    buffer1 = (byte[]) CopyArray(buffer1, new byte[(num2 - 1) + 1]);
                    int num5 = stream1.Read(buffer1, num3, buffer1.Length - num3);
                    num3 += num5;
                } // if
                do
                {
                    if ((num3 > 0) && helper1.IsTextFound(buffer1, num3))
                    {
                        return true;
                    } // if
                    num3 = stream1.Read(buffer1, 0, buffer1.Length);
                } while (num3 > 0);
                flag1 = false;
            } // try
            catch (Exception exception1)
            {
                if (
                    !
                    ((((exception1 is IOException) | (exception1 is NotSupportedException)) |
                      (exception1 is SecurityException)) | (exception1 is UnauthorizedAccessException)))
                {
                    throw;
                } // if
                return false;
            } // catch
            finally
            {
                if (stream1 != null)
                {
                    stream1.Close();
                } // if
            } // finally
            return flag1;
        } // FileContainsText

        private static Array CopyArray(Array arySrc, Array aryDest)
        {
            if (arySrc != null)
            {
                int num2 = arySrc.Length;
                if (num2 == 0)
                {
                    return aryDest;
                } // if
                if (aryDest.Rank != arySrc.Rank)
                {
                    throw new InvalidCastException(Resources.Array_RankMismatch);
                } // if
                int num8 = aryDest.Rank - 2;
                for (int num1 = 0; num1 <= num8; num1++)
                {
                    if (aryDest.GetUpperBound(num1) != arySrc.GetUpperBound(num1))
                    {
                        throw new ArrayTypeMismatchException(Resources.Array_TypeMismatch);
                    } // if
                } // for
                if (num2 > aryDest.Length)
                {
                    num2 = aryDest.Length;
                } // if
                if (arySrc.Rank > 1)
                {
                    int num4 = arySrc.Rank;
                    int num7 = arySrc.GetLength(num4 - 1);
                    int num6 = aryDest.GetLength(num4 - 1);
                    if (num6 != 0)
                    {
                        int num5 = Math.Min(num7, num6);
                        int num9 = (arySrc.Length/num7) - 1;
                        for (int num3 = 0; num3 <= num9; num3++)
                        {
                            Array.Copy(arySrc, num3*num7, aryDest, num3*num6, num5);
                        } // for
                    } // if
                    return aryDest;
                } // if
                Array.Copy(arySrc, aryDest, num2);
            } // if
            return aryDest;
        }

        /// <summary>
        /// Determines whether the specified path is absolute.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>
        /// 	<c>true</c> if the specified path is absolute; otherwise, <c>false</c>.
        /// </returns>
        private static bool IsRoot(string path)
        {
            if (!Path.IsPathRooted(path))
            {
                return false;
            } // if
            path = path.TrimEnd(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar});
            return (String.Compare(path, Path.GetPathRoot(path), StringComparison.OrdinalIgnoreCase) == 0);
        } // IsRoot


        private static void VerifyUICancelOption(string argName, UICancelOption argValue)
        {
            if ((argValue != UICancelOption.DoNothing) && (argValue != UICancelOption.ThrowException))
            {
                throw new InvalidEnumArgumentException(argName, (int) argValue, typeof (UICancelOption));
            } // if
        } // VerifyUICancelOption

        private static UIOptionInternal ToUIOptionInternal(UIOption showUI)
        {
            switch (showUI)
            {
                case UIOption.OnlyErrorDialogs:
                    {
                        return UIOptionInternal.OnlyErrorDialogs;
                    } // block
                case UIOption.AllDialogs:
                    {
                        return UIOptionInternal.AllDialogs;
                    } // block
            } // switch
            throw new InvalidEnumArgumentException("showUI", (int) showUI, typeof (UIOption));
        } // ToUIOptionInternal

        internal static string NormalizePath(string path)
        {
            return GetLongPath(RemoveEndingSeparator(Path.GetFullPath(path)));
        } // NormalizePath
        /// <summary>
        /// Removes the ending separator.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>The path.without any ending seperator</returns>
        private static string RemoveEndingSeparator(string path)
        {
            if (Path.IsPathRooted(path) && path.Equals(Path.GetPathRoot(path), StringComparison.OrdinalIgnoreCase))
            {
                return path;
            } // if
            return path.TrimEnd(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar});
        } // RemoveEndingSeparator

        /// <summary>Returns the parent path of the provided path.</summary>
        /// <returns>String.</returns>
        /// <param name="path">String. Path to be examined. Required. </param>
        private static string GetParentPathInternal(string path)
        {
            Path.GetFullPath(path);
            if (IsRoot(path))
            {
                throw new ArgumentException("path", String.Format(CultureInfo.InvariantCulture,
                                                                  Resources.IO_GetParentPathIsRoot_Path,
                                                                  new string[] {path}));
            } // if
            return Path.GetDirectoryName(path.TrimEnd(new char[]
                                                          {
                                                              Path.DirectorySeparatorChar,
                                                              Path.AltDirectorySeparatorChar
                                                          }));
        } // GetParentPath


        /// <summary>Combines two paths and returns a properly formatted path.</summary>
        /// <returns>String.</returns>
        /// <param name="baseDirectory">String. First path to be combined. Required. </param>
        /// <param name="relativePath">String. Second path to be combined. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string CombinePath(string baseDirectory, string relativePath)
        {
            if (String.IsNullOrEmpty(baseDirectory))
            {
                throw new ArgumentNullException("baseDirectory",
                                                String.Format(CultureInfo.InvariantCulture,
                                                              Resources.General_ArgumentEmptyOrNothing_Name,
                                                              new string[] {"baseDirectory"}));
            } // if

            if (String.IsNullOrEmpty(relativePath))
            {
                return baseDirectory;
            } // if
            baseDirectory = Path.GetFullPath(baseDirectory);
            return NormalizePath(Path.Combine(baseDirectory, relativePath));
        } // CombinePath

        internal static void CheckFilePathTrailingSeparator(string path, string paramName)
        {
            if (String.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(paramName);
            } // if
            if (path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) |
                path.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal))
            {
                throw new ArgumentException(Resources.IO_FilePathException, paramName);
            } // if
        } // CheckFilePathTrailingSeparator

        /// <summary>Copies a directory to another directory.</summary>
        /// <param name="overwrite">Boolean. Whether or not existing files should be overwritten. Default is False. Required.</param>
        /// <param name="destinationDirectoryName">String. The location to which the directory should be copied. Required.</param>
        /// <param name="sourceDirectoryName">String. The directory to be copied. Required.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyDirectory(string sourceDirectoryName, string destinationDirectoryName, bool overwrite)
        {
            CopyOrMoveDirectory(CopyOrMove.Copy, sourceDirectoryName, destinationDirectoryName, overwrite,
                                UIOptionInternal.NoUI, UICancelOption.ThrowException);
        } // CopyDirectory


        [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]
        private static void DemandDirectoryPermission(string fullDirectoryPath, FileIOPermissionAccess access)
        {
            if (
                !
                (fullDirectoryPath.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) |
                 fullDirectoryPath.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal)))
            {
                fullDirectoryPath = fullDirectoryPath + Path.DirectorySeparatorChar.ToString();
            } // if
            FileIOPermission permission1 = new FileIOPermission(access, fullDirectoryPath);
            permission1.Demand();
        } // DemandDirectoryPermission


        /// <summary>Copies a directory to another directory.</summary>
        /// <param name="destinationDirectoryName">String. The location to which the directory should be copied. Required.</param>
        /// <param name="sourceDirectoryName">String. The directory to be copied. Required.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyDirectory(string sourceDirectoryName, string destinationDirectoryName)
        {
            CopyOrMoveDirectory(CopyOrMove.Copy, sourceDirectoryName, destinationDirectoryName, false,
                                UIOptionInternal.NoUI, UICancelOption.ThrowException);
        } // CopyDirectory


        /// <summary>Copies a directory to another directory.</summary>
        /// <param name="showUI"><see cref="UIOption"></see>. Whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required.</param>
        /// <param name="destinationDirectoryName">String. The location to which the directory should be copied. Required.</param>
        /// <param name="sourceDirectoryName">String. The directory to be copied. Required.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyDirectory(string sourceDirectoryName, string destinationDirectoryName, UIOption showUI)
        {
            CopyOrMoveDirectory(CopyOrMove.Copy, sourceDirectoryName, destinationDirectoryName, false,
                                ToUIOptionInternal(showUI), UICancelOption.ThrowException);
        } // CopyDirectory


        /// <summary>Copies a file to a new location.</summary>
        /// <param name="sourceFileName">String. The file to be copied. Required. </param>
        /// <param name="onUserCancel"><see cref="UICancelOption"></see>. Specifies what should be done if the user clicks Cancel during the operation. Default is <see cref="UICancelOption.ThrowException"></see>. Required. </param>
        /// <param name="showUI"><see cref="UIOption"></see>. Whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required.</param>
        /// <param name="destinationFileName">String. The location to which the file should be copied. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyFile(string sourceFileName, string destinationFileName, UIOption showUI,
                             UICancelOption onUserCancel)
        {
            CopyOrMoveFile(CopyOrMove.Copy, sourceFileName, destinationFileName, false, ToUIOptionInternal(showUI),
                           onUserCancel);
        } // CopyFile


        /// <summary>Copies a file to a new location.</summary>
        /// <param name="sourceFileName">String. The file to be copied. Required. </param>
        /// <param name="overwrite">Boolean. Whether existing files should be overwritten. Default is False. Required. </param>
        /// <param name="destinationFileName">String. The location to which the file should be copied. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyFile(string sourceFileName, string destinationFileName, bool overwrite)
        {
            CopyOrMoveFile(CopyOrMove.Copy, sourceFileName, destinationFileName, overwrite, UIOptionInternal.NoUI,
                           UICancelOption.ThrowException);
        } // CopyFile

        /// <summary>Copies a file to a new location.</summary>
        /// <param name="sourceFileName">String. The file to be copied. Required. </param>
        /// <param name="showUI"><see cref="UIOption"></see>. Whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required.</param>
        /// <param name="destinationFileName">String. The location to which the file should be copied. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyFile(string sourceFileName, string destinationFileName, UIOption showUI)
        {
            CopyOrMoveFile(CopyOrMove.Copy, sourceFileName, destinationFileName, false, ToUIOptionInternal(showUI),
                           UICancelOption.ThrowException);
        } // CopyFile


        /// <summary>Copies a file to a new location.</summary>
        /// <param name="sourceFileName">String. The file to be copied. Required. </param>
        /// <param name="destinationFileName">String. The location to which the file should be copied. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyFile(string sourceFileName, string destinationFileName)
        {
            CopyOrMoveFile(CopyOrMove.Copy, sourceFileName, destinationFileName, false, UIOptionInternal.NoUI,
                           UICancelOption.ThrowException);
        } // CopyFile

        /// <summary>Creates a directory.</summary>
        /// <param name="directory">String. Name and location of the directory. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CreateDirectory(string directory)
        {
            directory = Path.GetFullPath(directory);
            if (Directory.Exists(directory))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryExists_Path,
                                  new string[] {directory}));
            } // if
            Directory.CreateDirectory(directory);
        } // CreateDirectory


        /// <summary>Copies a directory to another directory.</summary>
        /// <param name="onUserCancel"><see cref="UICancelOption"></see>. Specifies what should be done if the user clicks Cancel during the operation. Default is <see cref="UICancelOption.ThrowException"></see>. Required.</param>
        /// <param name="showUI"><see cref="UIOption"></see>. Whether to visually track the operation's progress. Default is UIOption.OnlyErrorDialogs. Required.</param>
        /// <param name="destinationDirectoryName">String. The location to which the directory should be copied. Required.</param>
        /// <param name="sourceDirectoryName">String. The directory to be copied. Required.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void CopyDirectory(string sourceDirectoryName, string destinationDirectoryName, UIOption showUI,
                                  UICancelOption onUserCancel)
        {
            CopyOrMoveDirectory(CopyOrMove.Copy, sourceDirectoryName, destinationDirectoryName, false,
                                ToUIOptionInternal(showUI), onUserCancel);
        } // CopyDirectory


        private static void CopyOrMoveDirectory(CopyOrMove operation, string sourceDirectoryName,
                                                string destinationDirectoryName, bool overwrite, UIOptionInternal showUI,
                                                UICancelOption onUserCancel)
        {
            VerifyUICancelOption("onUserCancel", onUserCancel);
            string source = NormalizePath(sourceDirectoryName);
            string target = NormalizePath(destinationDirectoryName);
            FileIOPermissionAccess access1 = FileIOPermissionAccess.Read;
            if (operation == CopyOrMove.Move)
            {
                access1 |= FileIOPermissionAccess.Write;
            } // if
            DemandDirectoryPermission(source, access1);
            DemandDirectoryPermission(target, FileIOPermissionAccess.Write | FileIOPermissionAccess.Read);
            ThrowIfDevicePath(source);
            ThrowIfDevicePath(target);

            if (!Directory.Exists(source))
            {
                throw new DirectoryNotFoundException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryNotFound_Path,
                                  new string[] {sourceDirectoryName}));
            } // if

            if (IsRoot(source))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryIsRoot_Path,
                                  new string[] {sourceDirectoryName}));
            } // if

            if (File.Exists(target))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_FileExists_Path,
                                  new string[] {destinationDirectoryName}));
            } // if
            if (target.Equals(source, StringComparison.OrdinalIgnoreCase))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_SourceEqualsTargetDirectory));
            } // if
            if (((target.Length > source.Length) &&
                 target.Substring(0, source.Length).Equals(source, StringComparison.OrdinalIgnoreCase)) &&
                (target[source.Length] == Path.DirectorySeparatorChar))
            {
                throw new InvalidOperationException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_SourceEqualsTargetDirectory));
            } // if
            if ((showUI != UIOptionInternal.NoUI) && Environment.UserInteractive)
            {
                ShellCopyOrMove(operation, FileOrDirectory.Directory, source, target, showUI, onUserCancel);
            } // if
            else
            {
                FxCopyOrMoveDirectory(operation, source, target, overwrite);
            } // else
        } // CopyOrMoveDirectory

        private static bool IsOnSameDrive(string path1, string path2)
        {
            path1 = path1.TrimEnd(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar});
            path2 = path2.TrimEnd(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar});
            return
                (string.Compare(Path.GetPathRoot(path1), Path.GetPathRoot(path2), StringComparison.OrdinalIgnoreCase) ==
                 0);
        } // IsOnSameDrive


        private static void FxCopyOrMoveDirectory(CopyOrMove operation, string sourceDirectoryPath,
                                                  string targetDirectoryPath, bool overwrite)
        {
            if (((operation == CopyOrMove.Move) & !Directory.Exists(targetDirectoryPath)) &
                IsOnSameDrive(sourceDirectoryPath, targetDirectoryPath))
            {
                Directory.CreateDirectory(GetParentPathInternal(targetDirectoryPath));
                try
                {
                    Directory.Move(sourceDirectoryPath, targetDirectoryPath);
                    return;
                } // try
                catch (IOException)
                {
                } // catch
                catch (UnauthorizedAccessException)
                {
                } // catch
            } // if
            Directory.CreateDirectory(targetDirectoryPath);
            DirectoryNode node1 = new DirectoryNode(sourceDirectoryPath, targetDirectoryPath);
            ListDictionary dictionary1 = new ListDictionary();
            CopyOrMoveDirectoryNode(operation, node1, overwrite, dictionary1);
            if (dictionary1.Count > 0)
            {
                IOException exception3 = new IOException(Resources.IO_CopyMoveRecursive);
                IDictionaryEnumerator enumerator1 = dictionary1.GetEnumerator();
                while (enumerator1.MoveNext())
                {
                    DictionaryEntry entry1 = (DictionaryEntry) enumerator1.Current;
                    exception3.Data.Add(entry1.Key, entry1.Value);
                } // while
                throw exception3;
            } // if
        } // FxCopyOrMoveDirectory

        private static void CopyOrMoveDirectoryNode(CopyOrMove operation, DirectoryNode sourceDirectoryNode,
                                                    bool overwrite, ListDictionary exceptions)
        {
            try
            {
                if (!Directory.Exists(sourceDirectoryNode.TargetPath))
                {
                    Directory.CreateDirectory(sourceDirectoryNode.TargetPath);
                } // if
            } // try
            catch (Exception exception1)
            {
                if (((!(exception1 is IOException) && !(exception1 is UnauthorizedAccessException)) &&
                     !(exception1 is DirectoryNotFoundException)) &&
                    (!(exception1 is NotSupportedException) && !(exception1 is SecurityException)))
                {
                    throw;
                } // if
                exceptions.Add(sourceDirectoryNode.Path, exception1.Message);
                return;
            } // catch
            if (!Directory.Exists(sourceDirectoryNode.TargetPath))
            {
                exceptions.Add(sourceDirectoryNode.TargetPath,
                               new DirectoryNotFoundException(
                                   String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryNotFound_Path,
                                                 new string[] {sourceDirectoryNode.TargetPath})));
            } // if
            else
            {
                IEnumerator<DirectoryNode> enumerator1 = null;
                string[] textArray2 = Directory.GetFiles(sourceDirectoryNode.Path);
                for (int num1 = 0; num1 < textArray2.Length; num1++)
                {
                    string text1 = textArray2[num1];
                    try
                    {
                        CopyOrMoveFile(operation, text1,
                                       Path.Combine(sourceDirectoryNode.TargetPath, Path.GetFileName(text1)), overwrite,
                                       UIOptionInternal.NoUI, UICancelOption.ThrowException);
                    } // try
                    catch (Exception exception2)
                    {
                        if (((!(exception2 is IOException) && !(exception2 is UnauthorizedAccessException)) &&
                             !(exception2 is SecurityException)) && !(exception2 is NotSupportedException))
                        {
                            throw;
                        } // if
                        exceptions.Add(text1, exception2.Message);
                    } // catch
                } // for
                try
                {
                    enumerator1 = sourceDirectoryNode.SubDirs.GetEnumerator();
                    while (enumerator1.MoveNext())
                    {
                        DirectoryNode node1 = enumerator1.Current;
                        CopyOrMoveDirectoryNode(operation, node1, overwrite, exceptions);
                    } // while
                } // try
                finally
                {
                    if (enumerator1 != null)
                    {
                        enumerator1.Dispose();
                    } // if
                } // finally
                if (operation == CopyOrMove.Move)
                {
                    try
                    {
                        Directory.Delete(sourceDirectoryNode.Path, false);
                    } // try
                    catch (Exception exception3)
                    {
                        if (((!(exception3 is IOException) && !(exception3 is UnauthorizedAccessException)) &&
                             !(exception3 is SecurityException)) && !(exception3 is DirectoryNotFoundException))
                        {
                            throw;
                        } // if
                        exceptions.Add(sourceDirectoryNode.Path, exception3.Message);
                        return;
                    } // catch
                } // if
            } // else
        } // CopyOrMoveDirectoryNode

        private static void CopyOrMoveFile(CopyOrMove operation, string sourceFileName, string destinationFileName,
                                           bool overwrite, UIOptionInternal showUI, UICancelOption onUserCancel)
        {
            VerifyUICancelOption("onUserCancel", onUserCancel);
            string text2 = NormalizeFilePath(sourceFileName, "sourceFileName");
            string text1 = NormalizeFilePath(destinationFileName, "destinationFileName");
            FileIOPermissionAccess access1 = FileIOPermissionAccess.Read;
            if (operation == CopyOrMove.Move)
            {
                access1 |= FileIOPermissionAccess.Write;
            } // if
            new FileIOPermission(access1, text2).Demand();
            new FileIOPermission(FileIOPermissionAccess.Write, text1).Demand();
            ThrowIfDevicePath(text2);
            ThrowIfDevicePath(text1);
            if (!File.Exists(text2))
            {
                throw new FileNotFoundException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_FileNotFound_Path,
                                  new string[] {sourceFileName}), sourceFileName);
            } // if
            if (Directory.Exists(text1))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryExists_Path,
                                  new string[] {destinationFileName}));
            } // if
            Directory.CreateDirectory(GetParentPathInternal(text1));
            if ((showUI != UIOptionInternal.NoUI) && Environment.UserInteractive)
            {
                ShellCopyOrMove(operation, FileOrDirectory.File, text2, text1, showUI, onUserCancel);
            } // if
            else if ((operation == CopyOrMove.Copy) || text2.Equals(text1, StringComparison.OrdinalIgnoreCase))
            {
                File.Copy(text2, text1, overwrite);
            } // if
            else if (overwrite)
            {
                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
                    try
                    {
                        if (
                            !
                            NativeMethods.MoveFileEx(text2, text1, NativeMethods.MoveFileFlags.MOVEFILE_REPLACE_EXISTING)
                            )
                        {
                            ThrowWinIOError(Marshal.GetLastWin32Error());
                        } // if
                    } // try
                    catch (Exception)
                    {
                        throw;
                    } // catch
                    finally
                    {
                        CodeAccessPermission.RevertAssert();
                    } // finally
                } // if
                else
                {
                    File.Delete(text1);
                    File.Move(text2, text1);
                } // else
            } // if
            else
            {
                File.Move(text2, text1);
            } // else
        } // CopyOrMoveFile


        private static void ShellCopyOrMove(CopyOrMove operation, FileOrDirectory targetType, string fullSourcePath,
                                            string fullTargetPath, UIOptionInternal showUI, UICancelOption onUserCancel)
        {
            NativeMethods.SHFileOperationType fileOperation;
            if (operation == CopyOrMove.Copy)
            {
                fileOperation = NativeMethods.SHFileOperationType.FO_COPY;
            } // if
            else
            {
                fileOperation = NativeMethods.SHFileOperationType.FO_MOVE;
            } // else
            NativeMethods.ShFileOperationFlags flags = GetOperationFlags(showUI);
            string sourcePath = fullSourcePath;
            if (targetType == FileOrDirectory.Directory)
            {
                if (Directory.Exists(fullTargetPath))
                {
                    sourcePath = Path.Combine(fullSourcePath, "*");
                } // if
                else
                {
                    Directory.CreateDirectory(GetParentPathInternal(fullTargetPath));
                } // else
            } // if
            ShellFileOperation(fileOperation, flags, sourcePath, fullTargetPath, onUserCancel, targetType);
            if ((((operation == CopyOrMove.Move) & (targetType == FileOrDirectory.Directory)) &&
                 Directory.Exists(fullSourcePath)) &&
                ((Directory.GetDirectories(fullSourcePath).Length == 0) &&
                 (Directory.GetFiles(fullSourcePath).Length == 0)))
            {
                Directory.Delete(fullSourcePath, false);
            } // if
        } // ShellCopyOrMove


        [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]
        [HostProtection(SecurityAction.LinkDemand, Resources = HostProtectionResource.ExternalProcessMgmt, UI = true)]
        private static void ShellFileOperation(NativeMethods.SHFileOperationType operationType,
                                               NativeMethods.ShFileOperationFlags operationFlags, string fullSource,
                                               string fullTarget, UICancelOption onUserCancel,
                                               FileOrDirectory isFileOrDirectory)
        {
            UIPermission permission = new UIPermission(UIPermissionWindow.SafeSubWindows);
            permission.Demand();
            FileIOPermissionAccess access = FileIOPermissionAccess.NoAccess;
            if (operationType == NativeMethods.SHFileOperationType.FO_COPY)
            {
                access = FileIOPermissionAccess.Read;
            } // if
            else if (operationType == NativeMethods.SHFileOperationType.FO_MOVE)
            {
                access = FileIOPermissionAccess.Write | FileIOPermissionAccess.Read;
            } // if
            else if (operationType == NativeMethods.SHFileOperationType.FO_DELETE)
            {
                access = FileIOPermissionAccess.Write;
            } // if
            string source = fullSource;
            if (((operationType == NativeMethods.SHFileOperationType.FO_COPY) ||
                 (operationType == NativeMethods.SHFileOperationType.FO_MOVE)) &&
                source.EndsWith("*", StringComparison.Ordinal))
            {
                source = RemoveEndingSeparator(fullSource.TrimEnd(new char[] {'*'}));
            } // if
            if (isFileOrDirectory == FileOrDirectory.Directory)
            {
                DemandDirectoryPermission(source, access);
            } // if
            else
            {
                new FileIOPermission(access, source).Demand();
            } // else
            if (operationType != NativeMethods.SHFileOperationType.FO_DELETE)
            {
                if (isFileOrDirectory == FileOrDirectory.Directory)
                {
                    DemandDirectoryPermission(fullTarget, FileIOPermissionAccess.Write);
                } // if
                else
                {
                    new FileIOPermission(FileIOPermissionAccess.Write, fullTarget).Demand();
                } // else
            } // if
            NativeMethods.SHFILEOPSTRUCT shfileopstruct1 =
                GetShellOperationInfo(operationType, operationFlags, fullSource, fullTarget);
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
            int ret;
            try
            {
                ret = NativeMethods.SHFileOperation(shfileopstruct1);
                NativeMethods.SHChangeNotify(NativeMethods.SHChangeEventType.SHCNE_DISKEVENTS,
                                             NativeMethods.SHChangeEventParameterFlags.SHCNF_DWORD, IntPtr.Zero,
                                             IntPtr.Zero);
            } // try
            catch (Exception)
            {
                throw;
            } // catch
            finally
            {
                CodeAccessPermission.RevertAssert();
            } // finally
            if (shfileopstruct1.fAnyOperationsAborted)
            {
                if (onUserCancel == UICancelOption.ThrowException)
                {
                    throw new OperationCanceledException();
                } // if
            } // if
            else if (ret != 0)
            {
                ThrowWinIOError(ret);
            } // if
        } // ShellFileOperation

        private static void ThrowWinIOError(int errorCode)
        {
            int num1 = errorCode;
            if (num1 == 2)
            {
                throw new FileNotFoundException();
            } // if
            if (num1 == 3)
            {
                throw new DirectoryNotFoundException();
            } // if
            if (num1 == 5)
            {
                throw new UnauthorizedAccessException();
            } // if
            if (num1 == 0xce)
            {
                throw new PathTooLongException();
            } // if
            if (num1 == 15)
            {
                throw new DriveNotFoundException();
            } // if
            if ((num1 != 0x3e3) && (num1 != 0x4c7))
            {
                throw new IOException(new Win32Exception(errorCode).Message, Marshal.GetHRForLastWin32Error());
            } // if
            throw new OperationCanceledException();
        } // ThrowWinIOError


        private static string GetShellPath(string FullPath)
        {
            return GetShellPath(new string[] {FullPath});
        } // GetShellPath


        private static string GetShellPath(string[] FullPaths)
        {
            StringBuilder builder1 = new StringBuilder();
            string[] textArray1 = FullPaths;
            for (int num1 = 0; num1 < textArray1.Length; num1++)
            {
                string text2 = textArray1[num1];
                builder1.Append(text2 + "\0");
            } // for
            return builder1.ToString();
        } // GetShellPath


        private static NativeMethods.SHFILEOPSTRUCT GetShellOperationInfo(
            NativeMethods.SHFileOperationType operationType, NativeMethods.ShFileOperationFlags operationFlags,
            string sourcePath, string targetPath /* = null */)
        {
            return GetShellOperationInfo(operationType, operationFlags, new string[] {sourcePath}, targetPath);
        } // GetShellOperationInfo

        private static NativeMethods.SHFILEOPSTRUCT GetShellOperationInfo(
            NativeMethods.SHFileOperationType operationType, NativeMethods.ShFileOperationFlags operationFlags,
            string[] sourcePath, string targetPath /* = null */)
        {
            NativeMethods.SHFILEOPSTRUCT shFileOperation = new NativeMethods.SHFILEOPSTRUCT();
            shFileOperation.wFunc = operationType;
            shFileOperation.fFlags = operationFlags;
            shFileOperation.pFrom = GetShellPath(sourcePath);
            if (targetPath == null)
            {
                shFileOperation.pTo = null;
            } // if
            else
            {
                shFileOperation.pTo = GetShellPath(targetPath);
            } // else
            shFileOperation.hNameMappings = IntPtr.Zero;
            try
            {
                shFileOperation.hwnd = Process.GetCurrentProcess().MainWindowHandle;
            } // try
            catch (Exception exception1)
            {
                if ((!(exception1 is SecurityException) && !(exception1 is InvalidOperationException)) &&
                    !(exception1 is NotSupportedException))
                {
                    throw;
                } // if
                shFileOperation.hwnd = IntPtr.Zero;
            } // catch
            shFileOperation.lpszProgressTitle = string.Empty;
            return shFileOperation;
        } // GetShellOperationInfo


        private static NativeMethods.ShFileOperationFlags GetOperationFlags(UIOptionInternal showUI)
        {
            NativeMethods.ShFileOperationFlags flags = NativeMethods.ShFileOperationFlags.FOF_NOCONFIRMMKDIR |
                                                       NativeMethods.ShFileOperationFlags.FOF_NO_CONNECTED_ELEMENTS;
            if (showUI == UIOptionInternal.OnlyErrorDialogs)
            {
                flags |= NativeMethods.ShFileOperationFlags.FOF_SILENT |
                         NativeMethods.ShFileOperationFlags.FOF_NOCONFIRMATION;
            } // if
            return flags;
        } // GetOperationFlags


        /// <summary>Writes data to a binary file.</summary>
        /// <param name="file">String. Path and name of the file to be written to. Required. </param>
        /// <param name="data">Byte. Data to be written to the file. Required. </param>
        /// <param name="append">Boolean. Whether to append or overwrite data. Default is False. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void WriteAllBytes(string file, byte[] data, bool append)
        {
            if (String.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException("file");
            }

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            CheckFilePathTrailingSeparator(file, "file");

            FileMode mode1;

            if (append)
            {
                mode1 = FileMode.Append;
            } // if
            else
            {
                mode1 = FileMode.Create;
            } // else

            using (FileStream stream1 = new FileStream(file, mode1, FileAccess.Write, FileShare.Read))
            {
                stream1.Write(data, 0, data.Length);
            } // using
        } // WriteAllBytes


        private static void ThrowIfDevicePath(string path)
        {
            if (path.StartsWith(@"\\.\", StringComparison.Ordinal))
            {
                throw new ArgumentException("path", Resources.IO_DevicePath);
            } // if
        } // ThrowIfDevicePath

        internal static string NormalizeFilePath(string Path, string ParamName)
        {
            CheckFilePathTrailingSeparator(Path, ParamName);
            return NormalizePath(Path);
        } // NormalizeFilePath


        private static void EnsurePathNotExist(string path)
        {
            if (File.Exists(path))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_FileExists_Path, new string[] {path}));
            } // if
            if (Directory.Exists(path))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryExists_Path, new string[] {path}));
            } // if
        } // EnsurePathNotExist


        /// <summary>Renames a file.</summary>
        /// <param name="file">String. File to be renamed. Required. </param>
        /// <param name="newName">String. New name of file. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void RenameFile(string file, string newName)
        {
            file = NormalizeFilePath(file, "file");

            ThrowIfDevicePath(file);

            if (!File.Exists(file))
            {
                throw new FileNotFoundException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_FileNotFound_Path, new string[] {file}),
                    file);
            } // if

            if (String.IsNullOrEmpty(newName))
            {
                throw new ArgumentNullException("newName",
                                                String.Format(CultureInfo.InvariantCulture,
                                                              Resources.General_ArgumentEmptyOrNothing_Name,
                                                              new string[] {"newName"}));
            } // if

            string text1 = GetFullPathFromNewName(GetParentPathInternal(file), newName, "newName");
            EnsurePathNotExist(text1);
            File.Move(file, text1);
        } // RenameFile

        private static string GetFullPathFromNewName(string path, string newName, string argumentName)
        {
            if (newName.IndexOfAny(SeparatorChars) >= 0)
            {
                throw new ArgumentException(
                    String.Format(CultureInfo.InvariantCulture, Resources.General_ArgumentEmptyOrNothing_Name,
                                  new string[] {argumentName, newName}), argumentName);
            } // if
            string text1 = RemoveEndingSeparator(Path.GetFullPath(Path.Combine(path, newName)));

            if (!GetParentPathInternal(text1).Equals(path, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_ArgumentIsPath_Name_Path,
                                  new string[] {argumentName, newName}), argumentName);
            } // if
            return text1;
        } // GetFullPathFromNewName


        /// <summary>Writes text to a file.</summary>
        /// <param name="file">String. File to be written to. Required. </param>
        /// <param name="append">Boolean. Whether to append text or overwrite existing text. Default is False. Required. </param>
        /// <param name="text">String. Text to be written to file. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void WriteAllText(string file, string text, bool append)
        {
            this.WriteAllText(file, text, append, Encoding.UTF8);
        } // WriteAllText


        /// <summary>Writes text to a file.</summary>
        /// <param name="file">String. File to be written to. Required. </param>
        /// <param name="encoding"><see cref="T:System.Text.Encoding"></see>. What encoding to use when writing to file. Required. Default is UTF-8.</param>
        /// <param name="append">Boolean. Whether to append text or overwrite existing text. Default is False. Required. </param>
        /// <param name="text">String. Text to be written to file. Required. </param>
        /// <remarks>
        ///		If the specified encoding does not match the existing encoding of the file,
        ///		the specified coding will be ignored.
        /// </remarks>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void WriteAllText(string file, string text, bool append, Encoding encoding)
        {
            if (append && File.Exists(file))
            {
                try
                {
                    using (StreamReader reader1 = new StreamReader(file, encoding, true))
                    {
                        char[] chArray1 = new char[10];
                        reader1.Read(chArray1, 0, 10);
                        encoding = reader1.CurrentEncoding;
                    } // using
                } // try
                catch (IOException)
                {
                } // catch
            } // if

            using (StreamWriter writer1 = new StreamWriter(file, append, encoding))
            {
                writer1.Write(text);
            } // using
        } // WriteAllText

        /// <summary>Returns the contents of a text file as a String.</summary>
        /// <returns>String containing the contents of the file.</returns>
        /// <param name="file">String. Name and path of the file to read. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string ReadAllText(string file)
        {
            return File.ReadAllText(file);
        } // ReadAllText


        /// <summary>Returns the contents of a file as a byte array.</summary>
        /// <returns>Byte array containing the contents of the file.</returns>
        /// <param name="file">String. File to be read. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public byte[] ReadAllBytes(string file)
        {
            return File.ReadAllBytes(file);
        } // ReadAllBytes

        /// <summary>
        /// Reads the file into memory.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public MemoryStream ReadFileIntoMemory(string file)
        {
            if (File.Exists(file))
            {
                byte[] contents = this.ReadAllBytes(file);
                MemoryStream memory = new MemoryStream(contents);
                return memory;
            }
            return null;
        } // ReadIntoMemory

        /// <summary>
        /// Writes the file from memory.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="contents">The contents.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void WriteFileFromMemory(string file, MemoryStream contents)
        {
            if (String.IsNullOrEmpty(file))
            {
                throw new ArgumentNullException("file");
            }

            if (contents == null)
            {
                throw new ArgumentNullException("contents");
            }

            byte[] data = contents.ToArray();

            this.WriteAllBytes(file, data, false);
        } // WriteFileFromMemory


        /// <summary>Renames a directory.</summary>
        /// <param name="newName">String. New name for directory. Required. </param>
        /// <param name="directory">String. Path and name of directory to be renamed. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void RenameDirectory(string directory, string newName)
        {
            directory = Path.GetFullPath(directory);
            ThrowIfDevicePath(directory);
            if (IsRoot(directory))
            {
                throw new IOException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryIsRoot_Path,
                                  new string[] {directory}));
            } // if
            if (!Directory.Exists(directory))
            {
                throw new DirectoryNotFoundException(
                    String.Format(CultureInfo.InvariantCulture, Resources.IO_DirectoryNotFound_Path,
                                  new string[] {directory}));
            } // if
            if (String.IsNullOrEmpty(newName))
            {
                throw new ArgumentNullException("newName",
                                                String.Format(CultureInfo.InvariantCulture,
                                                              Resources.General_ArgumentEmptyOrNothing_Name,
                                                              new string[] {"newName"}));
            } // if

            string text1 = GetFullPathFromNewName(GetParentPathInternal(directory), newName, "newName");
            EnsurePathNotExist(text1);
            Directory.Move(directory, text1);
        } // RenameDirectory


        /// <summary>Opens a <see cref="T:System.IO.StreamWriter"></see>.</summary>
        /// <returns><see cref="T:System.IO.StreamWriter"></see></returns>
        /// <param name="file">String. File to be written to. Required. </param>
        /// <param name="encoding"><see cref="T:System.Text.Encoding"></see>. Encoding to be used in writing to the file. Default is ASCII. Required. </param>
        /// <param name="append">Boolean. Specifies whether to append to or overwrite information in the file. Default is False. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public StreamWriter OpenTextFileWriter(string file, bool append, Encoding encoding)
        {
            file = NormalizeFilePath(file, "file");
            return new StreamWriter(file, append, encoding);
        } // OpenTextFileWriter


        /// <summary>Opens a <see cref="T:System.IO.StreamWriter"></see>.</summary>
        /// <returns><see cref="T:System.IO.StreamWriter"></see></returns>
        /// <param name="file">String. File to be written to. Required. </param>
        /// <param name="append">Boolean. Specifies whether to append to or overwrite information in the file. Default is False. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public StreamWriter OpenTextFileWriter(string file, bool append)
        {
            return this.OpenTextFileWriter(file, append, Encoding.UTF8);
        } // OpenTextFileWriter


        /// <summary>Opens a <see cref="T:System.IO.StreamReader"></see>.</summary>
        /// <returns><see cref="StreamReader"></see></returns>
        /// <param name="file">String. File to be read. Required. </param>
        /// <param name="encoding"><see cref="T:System.Text.Encoding"></see>. Default is ASCII. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public StreamReader OpenTextFileReader(string file, Encoding encoding)
        {
            file = NormalizeFilePath(file, "file");
            return new StreamReader(file, encoding, true);
        } // OpenTextFileReader


        /// <summary>Opens a <see cref="T:System.IO.StreamReader"></see>.</summary>
        /// <returns><see cref="StreamReader"></see></returns>
        /// <param name="file">String. File to be read. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public StreamReader OpenTextFileReader(string file)
        {
            return this.OpenTextFileReader(file, Encoding.UTF8);
        } // OpenTextFileReader

        /// <summary>The OpenTextFieldParser method allows you to create a TextFieldParser Object, which provides a way to easily and efficiently parse structured text files, such as logs. The TextFieldParser object can be used to read both delimited and fixed-width files.</summary>
        /// <returns><see cref="TextFieldParser"></see></returns>
        /// <param name="file">String. The file to be opened with the TextFieldParser. Required.</param>
        /// <param name="delimiters">String(). Delimiters for the fields. Required.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public TextFieldParser OpenTextFieldParser(string file, params string[] delimiters)
        {
            TextFieldParser parser2 = new TextFieldParser(file);
            parser2.SetDelimiters(delimiters);
            parser2.TextFieldType = FieldType.Delimited;
            return parser2;
        } // OpenTextFieldParser

        /// <summary>The OpenTextFieldParser method allows you to create a TextFieldParser Object, which provides a way to easily and efficiently parse structured text files, such as logs. The TextFieldParser object can be used to read both delimited and fixed-width files.</summary>
        /// <returns><see cref="TextFieldParser"></see></returns>
        /// <param name="file">String. The file to be opened with the TextFieldParser. Required.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public TextFieldParser OpenTextFieldParser(string file)
        {
            return new TextFieldParser(file);
        } // OpenTextFieldParser


        /// <summary>The OpenTextFieldParser method allows you to create a TextFieldParser Object, which provides a way to easily and efficiently parse structured text files, such as logs. The TextFieldParser object can be used to read both delimited and fixed-width files.</summary>
        /// <returns><see cref="TextFieldParser"></see></returns>
        /// <param name="file">String. The file to be opened with the TextFieldParser. Required.</param>
        /// <param name="fieldWidths">Integer(). Widths of the fields. Required.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public TextFieldParser OpenTextFieldParser(string file, params int[] fieldWidths)
        {
            TextFieldParser parser2 = new TextFieldParser(file);
            parser2.SetFieldWidths(fieldWidths);
            parser2.TextFieldType = FieldType.FixedWidth;
            return parser2;
        } // OpenTextFieldParser

        /// <summary>Returns the contents of a text file as a String.</summary>
        /// <returns>String containing the contents of the file.</returns>
        /// <param name="file">String. Name and path of the file to read. Required. </param>
        /// <param name="encoding"><see cref="T:System.Text.Encoding"></see>. Character encoding to use in reading the file. Required. Default is UTF-8.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string ReadAllText(string file, Encoding encoding)
        {
            return File.ReadAllText(file, encoding);
        } // ReadAllText


        /// <summary>
        /// Gets the long path.
        /// </summary>
        /// <param name="fullPath">The full path.</param>
        /// <returns></returns>
        private static string GetLongPath(string fullPath)
        {
            string text1;
            try
            {
                if (IsRoot(fullPath))
                {
                    return fullPath;
                } // if
                DirectoryInfo info1 = new DirectoryInfo(GetParentPathInternal(fullPath));
                if (File.Exists(fullPath))
                {
                    return info1.GetFiles(Path.GetFileName(fullPath))[0].FullName;
                } // if
                if (Directory.Exists(fullPath))
                {
                    return info1.GetDirectories(Path.GetFileName(fullPath))[0].FullName;
                } // if
                text1 = fullPath;
            } // try
            catch (Exception ex)
            {
                if ((((!(ex is ArgumentException) && !(ex is ArgumentNullException)) && !(ex is PathTooLongException)) &&
                     (!(ex is NotSupportedException) && !(ex is DirectoryNotFoundException))) &&
                    (!(ex is SecurityException) && !(ex is UnauthorizedAccessException)))
                {
                    throw;
                } // if
                text1 = fullPath;
            } // catch
            return text1;
        } // GetLongPath


        private static void AddToStringCollection(Collection<string> StrCollection, string[] StrArray)
        {
            if (StrArray != null)
            {
                string[] textArray1 = StrArray;
                for (int num1 = 0; num1 < textArray1.Length; num1++)
                {
                    string text1 = textArray1[num1];
                    if (!StrCollection.Contains(text1))
                    {
                        StrCollection.Add(text1);
                    } // if
                } // for
            } // if
        } // AddToStringCollection


        private static string[] FindPaths(FileOrDirectory FileOrDirectory, string directory, string wildCard)
        {
            if (FileOrDirectory == FileOrDirectory.Directory)
            {
                if (String.IsNullOrEmpty(wildCard))
                {
                    return Directory.GetDirectories(directory);
                } // if
                return Directory.GetDirectories(directory, wildCard);
            } // if
            if (String.IsNullOrEmpty(wildCard))
            {
                return Directory.GetFiles(directory);
            } // if
            return Directory.GetFiles(directory, wildCard);
        } // FindPaths

        private static void FindFilesOrDirectories(FileOrDirectory FileOrDirectory, string directory,
                                                   SearchOption searchType, string[] wildcards,
                                                   Collection<string> Results)
        {
            VerifySearchOption("searchType", searchType);
            directory = NormalizePath(directory);
            if (wildcards != null)
            {
                string[] textArray1 = wildcards;
                for (int num1 = 0; num1 < textArray1.Length; num1++)
                {
                    string text1 = textArray1[num1];
                    if (String.Compare(text1.TrimEnd(new char[0]), "", true, CultureInfo.InvariantCulture) == 0)
                    {
                        throw new ArgumentNullException("wildcards", Resources.IO_GetFiles_NullPattern);
                    } // if
                } // for
            } // if
            if ((wildcards == null) || (wildcards.Length == 0))
            {
                AddToStringCollection(Results, FindPaths(FileOrDirectory, directory, null));
            } // if
            else
            {
                string[] textArray2 = wildcards;
                for (int num2 = 0; num2 < textArray2.Length; num2++)
                {
                    string text2 = textArray2[num2];
                    AddToStringCollection(Results, FindPaths(FileOrDirectory, directory, text2));
                } // for
            } // else
            if (searchType == SearchOption.SearchAllSubdirectories)
            {
                string[] textArray3 = Directory.GetDirectories(directory);
                for (int num3 = 0; num3 < textArray3.Length; num3++)
                {
                    string text3 = textArray3[num3];
                    FindFilesOrDirectories(FileOrDirectory, text3, searchType, wildcards, Results);
                } // for
            } // if
        } // FindFilesOrDirectories

        private static ReadOnlyCollection<string> FindFilesOrDirectories(FileOrDirectory FileOrDirectory,
                                                                         string directory, SearchOption searchType,
                                                                         string[] wildcards)
        {
            Collection<string> collection2 = new Collection<string>();
            FindFilesOrDirectories(FileOrDirectory, directory, searchType, wildcards, collection2);
            return new ReadOnlyCollection<string>(collection2);
        } // FindFilesOrDirectories

        /// <summary>Returns a collection of strings representing the path names of subdirectories within a directory.</summary>
        /// <returns>Read-only collection of String.</returns>
        /// <param name="directory">String. Name and path of directory. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<string> GetDirectories(string directory)
        {
            return FindFilesOrDirectories(FileOrDirectory.Directory, directory, SearchOption.SearchTopLevelOnly, null);
        } // GetDirectories

        /// <summary>Returns a collection of strings representing the path names of subdirectories within a directory.</summary>
        /// <returns>Read-only collection of String.</returns>
        /// <param name="directory">String. Name and path of directory. Required. </param>
        /// <param name="wildcards">String. Pattern to match names. Required. </param>
        /// <param name="searchType">SearchOption Enumeration. Whether to include subfolders. Default is SearchOption.SearchTopLevelOnly. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<string> GetDirectories(string directory, SearchOption searchType,
                                                         params string[] wildcards)
        {
            return FindFilesOrDirectories(FileOrDirectory.Directory, directory, searchType, wildcards);
        } // GetDirectories

        /// <summary>Returns a <see cref="T:System.IO.DirectoryInfo"></see> object for the specified path.</summary>
        /// <returns><see cref="T:System.IO.DirectoryInfo"></see></returns>
        /// <param name="directory">String. Path of directory. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public DirectoryInfo GetDirectoryInfo(string directory)
        {
            return new DirectoryInfo(directory);
        } // GetDirectoryInfo

        /// <summary>Returns a <see cref="T:System.IO.DriveInfo"></see> object for the specified drive.</summary>
        /// <returns><see cref="T:System.IO.DriveInfo"></see></returns>
        /// <param name="drive">String. Drive to be examined. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public DriveInfo GetDriveInfo(string drive)
        {
            return new DriveInfo(drive);
        } // GetDriveInfo

        /// <summary>Returns a <see cref="T:System.IO.FileInfo"></see> object for the specified file.</summary>
        /// <returns><see cref="T:System.IO.FileInfo"></see></returns>
        /// <param name="file">String. Name and path of the file. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public FileInfo GetFileInfo(string file)
        {
            file = NormalizeFilePath(file, "file");
            return new FileInfo(file);
        } // GetFileInfo

        /// <summary>Returns a read-only collection of strings representing the names of files within a directory.</summary>
        /// <returns>Read-only collection of strings.</returns>
        /// <param name="directory">String. Directory to be searched. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<string> GetFiles(string directory)
        {
            return FindFilesOrDirectories(FileOrDirectory.File, directory, SearchOption.SearchTopLevelOnly, null);
        } // GetFiles

        /// <summary>Returns a read-only collection of strings representing the names of files within a directory.</summary>
        /// <returns>Read-only collection of strings.</returns>
        /// <param name="directory">String. Directory to be searched. Required. </param>
        /// <param name="wildcards">String. Pattern to be matched. Required. </param>
        /// <param name="searchType">SearchOption Enumeration. Whether to include subfolders. Default is SearchOption.SearchTopLevelOnly. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public ReadOnlyCollection<string> GetFiles(string directory, SearchOption searchType, params string[] wildcards)
        {
            return FindFilesOrDirectories(FileOrDirectory.File, directory, searchType, wildcards);
        } // GetFiles

        /// <summary>Parses the file name out of the path provided.</summary>
        /// <returns>String.</returns>
        /// <param name="path">Required. Path to be parsed. String.</param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string GetName(string path)
        {
            return Path.GetFileName(path);
        } // GetName

        /// <summary>Returns the parent path of the provided path.</summary>
        /// <returns>String.</returns>
        /// <param name="path">String. Path to be examined. Required. </param>
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public string GetParentPath(string path)
        {
            return GetParentPathInternal(path);
        } // GetParentPath

        #endregion

        #region DirectoryNode

        private class DirectoryNode
        {
            internal DirectoryNode(string DirectoryPath, string TargetDirectoryPath)
            {
                this.m_Path = DirectoryPath;
                this.m_TargetPath = TargetDirectoryPath;
                this.m_SubDirs = new Collection<DirectoryNode>();
                string[] textArray1 = Directory.GetDirectories(this.m_Path);
                for (int num1 = 0; num1 < textArray1.Length; num1++)
                {
                    string text1 = textArray1[num1];
                    string text2 = System.IO.Path.Combine(this.m_TargetPath, System.IO.Path.GetFileName(text1));
                    this.m_SubDirs.Add(new DirectoryNode(text1, text2));
                } // for
            } // DirectoryNode


            internal string Path
            {
                get { return this.m_Path; } // get
            } // Path

            internal Collection<DirectoryNode> SubDirs
            {
                get { return this.m_SubDirs; } // get
            } // SubDirs

            internal string TargetPath
            {
                get { return this.m_TargetPath; } // get
            } // TargetPath


            private string m_Path;
            private Collection<DirectoryNode> m_SubDirs;
            private string m_TargetPath;
        } // class DirectoryNode

        #endregion

        #region TextSearchHelper

        private class TextSearchHelper
        {
            private TextSearchHelper()
            {
                this.m_PreviousCharBuffer = new char[0];
                this.m_CheckPreamble = true;
            } // TextSearchHelper


            internal TextSearchHelper(Encoding Encoding, string Text, bool IgnoreCase)
            {
                this.m_PreviousCharBuffer = new char[0];
                this.m_CheckPreamble = true;
                this.m_Decoder = Encoding.GetDecoder();
                this.m_Preamble = Encoding.GetPreamble();
                this.m_IgnoreCase = IgnoreCase;
                if (this.m_IgnoreCase)
                {
                    this.m_SearchText = Text.ToUpper(CultureInfo.CurrentCulture);
                } // if
                else
                {
                    this.m_SearchText = Text;
                } // else
            } // TextSearchHelper


            private static bool BytesMatch(byte[] BigBuffer, byte[] SmallBuffer)
            {
                if ((BigBuffer.Length < SmallBuffer.Length) | (SmallBuffer.Length == 0))
                {
                    return false;
                } // if
                int num2 = SmallBuffer.Length - 1;
                for (int num1 = 0; num1 <= num2; num1++)
                {
                    if (BigBuffer[num1] != SmallBuffer[num1])
                    {
                        return false;
                    } // if
                } // for
                return true;
            } // BytesMatch

            internal bool IsTextFound(byte[] ByteBuffer, int Count)
            {
                int num1 = 0;
                if (this.m_CheckPreamble)
                {
                    if (BytesMatch(ByteBuffer, this.m_Preamble))
                    {
                        num1 = this.m_Preamble.Length;
                        Count -= this.m_Preamble.Length;
                    } // if
                    this.m_CheckPreamble = false;
                    if (Count <= 0)
                    {
                        return false;
                    } // if
                } // if
                int num3 = this.m_Decoder.GetCharCount(ByteBuffer, num1, Count);
                char[] chArray1 = new char[((this.m_PreviousCharBuffer.Length + num3) - 1) + 1];
                Array.Copy(this.m_PreviousCharBuffer, 0, chArray1, 0, this.m_PreviousCharBuffer.Length);
                //int num2 = this.m_Decoder.GetChars(ByteBuffer, num1, Count, chArray1, this.m_PreviousCharBuffer.Length);
                if (chArray1.Length > this.m_SearchText.Length)
                {
                    if (this.m_PreviousCharBuffer.Length != this.m_SearchText.Length)
                    {
                        this.m_PreviousCharBuffer = new char[(this.m_SearchText.Length - 1) + 1];
                    } // if
                    Array.Copy(chArray1, chArray1.Length - this.m_SearchText.Length, this.m_PreviousCharBuffer, 0,
                               this.m_SearchText.Length);
                } // if
                else
                {
                    this.m_PreviousCharBuffer = chArray1;
                } // else
                if (this.m_IgnoreCase)
                {
                    return new string(chArray1).ToUpper(CultureInfo.CurrentCulture).Contains(this.m_SearchText);
                } // if
                return new string(chArray1).Contains(this.m_SearchText);
            } // IsTextFound 

            private bool m_CheckPreamble;
            private Decoder m_Decoder;
            private bool m_IgnoreCase;
            private byte[] m_Preamble;
            private char[] m_PreviousCharBuffer;
            private string m_SearchText;
        } // class TextSearchHelper

        #endregion

        #region CopyOrMove

        private enum CopyOrMove
        {
            Copy,
            Move
        }

        #endregion

        #region UIOptionInternal

        private enum UIOptionInternal
        {
            AllDialogs = 3,
            NoUI = 4,
            OnlyErrorDialogs = 2
        }

        #endregion

        #region FileOrDirectory

        private enum FileOrDirectory
        {
            File,
            Directory
        }

        #endregion
    }
}